﻿using System;
using System.Web.Mvc;
using System.Web.UI;
using GameOn.Web.Entities;
using GameOn.Web.Models;
using GameOn.Web.Services;

namespace GameOn.Web.Controllers
{
    /// <summary>
    /// A Matches controller. Controls views for listing and playing matches
    /// </summary>
    public class MatchesController : Controller
    {
        private GameOnEntities Entities { get; set; }
        private IMatchResultEntryService MatchResultEntryService { get; set; }
        private IPlayerService PlayerService { get; set; }
        private IMatchService MatchService { get; set; }
        private IPlayerRegistrationService PlayerRegistrationService { get; set; }

        public MatchesController()
        {
            Entities = new GameOnEntities();
            MatchResultEntryService = new MatchResultEntryService(Entities);
            PlayerService = new PlayerService(Entities);
            MatchService = new MatchService();
            PlayerRegistrationService = new PlayerRegistrationService(Entities);
        }

        /// <summary>
        /// Gets a list of the last 100 matches played, optionally for a given player's ID
        /// </summary>
        [HttpGet]
        public ActionResult Index(int? playerId)
        {
            var model = new PlayerMatchListModel();

            if (playerId.HasValue)
            {
                model.Matches = MatchService.GetMatches(playerId.Value, new { PageSize = 100 });
                model.Player = PlayerService.GetPlayer(playerId.Value);
                model.PlayerMatchesSummary = PlayerService.GetPlayerMatchesSummary(playerId.Value);
                ViewData.Model = model;
                return View("Index_m");                
            }

            model.Matches = MatchService.GetMatches(new { PageSize = 100 });
            ViewData.Model = model;
            return View("Index_m");
        }

        /// <summary>
        /// Returns a view that prompts to Start a new Game. When no player1 ID is provided, prompts for Player 1. When a player1 ID is provided, prompts for player 2
        /// </summary>
        /// <param name="player1"></param>
        /// <returns></returns>
        [HttpGet]
        [OutputCache (Duration = 0, NoStore = true, Location = OutputCacheLocation.None)]
        public ActionResult New(int? player1)
        {
            ViewBag.Player1 = player1;
            ViewData.Model = PlayerService.GetPlayersByRank();
            return View("New_m");
        }

        /// <summary>
        /// Starts a new game and creates a player at the same time. If player1 is not provided, the playerName will be used to create a new player, who will be player 1 for this match, and
        /// the action will redirect to prompt for player 2. If player1 is provided, playerName will be used to create a new player who will be player 2 for this match, and the action will
        /// redirect to the Play action.
        /// </summary>
        /// <param name="player1">Optional. Player 1's ID</param>
        /// <param name="playerName">Required. A Player name.</param>
        /// <returns>Returns the result of either the New or Play action.</returns>
        [HttpPost]
        public ActionResult New(int? player1, string playerName)
        {
            if (string.IsNullOrWhiteSpace(playerName)) throw new ArgumentNullException("playerName");

            int playerId = PlayerRegistrationService.AddPlayer(new Player {Name = playerName, Fullname = playerName, Email = playerName, CurrentRank = 1000});

            if (player1.HasValue) return Play(player1.Value, playerId);
            return New(playerId);
        }

        /// <summary>
        /// Returns a view to display while a game is being played.
        /// </summary>
        [HttpGet]
        [OutputCache(Duration = 30, Location = OutputCacheLocation.Any, VaryByParam = "player1;player2")]
        public ActionResult Play(int player1, int player2)
        {
            var model = new PlayModel();
            model.Player1 = PlayerService.GetPlayer(player1);
            model.Player2 = PlayerService.GetPlayer(player2);
            ViewData.Model = model;
            return View("Play_m");
        }

        /// <summary>
        /// Redirects to the New action. Here to prevent missing param exceptions in jQuery Mobile
        /// </summary>
        [HttpGet]
        public ActionResult Played()
        {
            return RedirectToAction("New");
        }

        /// <summary>
        /// Enters the results of a Match that has just been played.
        /// </summary>
        /// <param name="player1">Player 1's ID</param>
        /// <param name="player2">Player 2's ID</param>
        /// <param name="winnerId">The winning player's ID</param>
        /// <param name="score">The score expressed as a string</param>
        /// <returns>The Played view</returns>
        [HttpPost]
        public ActionResult Played(int player1, int player2, int winnerId, string score)
        {
            ViewData.Model = MatchResultEntryService.Played(player1, player2, winnerId, score);
            return View("Played_m");
        }
    }
}
